<?php

namespace app\common\service;


/**
 * 公共服务类
 *
 * Class CommonService
 * @package app\common\service
 */
class CommonService {


    /**
     * 唯一数字编码
     * @param integer $size 编码长度
     * @param string $prefix 编码前缀
     * @return string
     */
    public static function uniqidNumber( $size, $prefix = '')
    {
        $time = time() . '';
        if (empty($size) || $size < 10) $size = 12;
        $code = $prefix . (intval($time[0]) + intval($time[1])) . substr($time, 2) . rand(0, 9);
        while (strlen($code) < $size) $code .= rand(0, 9);
        return $code;
    }


    /**
     * 获取两个时间相差了多少个月，工龄
     *
     * @param $date1   "2013-07-01"
     * @param $date2   "2015-02-01"
     * @param string $tags
     * @return float|int
     */
    public static function getMonthNum($date1, $date2, $tags = '-')
    {
        $d1 = explode($tags, $date1);
        $d2 = explode($tags, $date2);
        if (strtotime($date1) - strtotime($date2) > 0) {
            $monthsFromYear = abs($d1[0] - $d2[0]) * 12;
            $monthsFromMonth = $d1[1] - $d2[1];
            return $monthsFromYear + $monthsFromMonth;
        } else {
            $monthsFromYear = abs($d2[0] - $d1[0]) * 12;
            $monthsFromMonth = $d2[1] - $d1[1];
            return $monthsFromYear + $monthsFromMonth;
        }
    }


    /**
     * 获取两个日期之间的间隔
     */
    public static function getBetweenDayNum($end_data,$start_data) {

        $end_data = strtotime($end_data);
        $start_data = strtotime($start_data);
        $days = ceil(abs($end_data - $start_data)/86400);
        return $days;
    }

    /**
     * 下划线转驼峰
     * 思路:
     * step1.原字符串转小写,原字符串中的分隔符用空格替换,在字符串开头加上分隔符
     * step2.将字符串中每个单词的首字母转换为大写,再去空格,去字符串首部附加的分隔符.
     * @param $uncamelized_words
     * @param string $separator
     * @return string
     */
    public static function camelize($uncamelized_words,$separator='_')
    {
        $uncamelized_words = $separator. str_replace($separator, " ", strtolower($uncamelized_words));
        return ltrim(str_replace(" ", "", ucwords($uncamelized_words)), $separator );
    }


    /**
     * 驼峰命名转下划线命名
     * 思路:
     * @param $camelCaps
     * @param string $separator
     * @return string
     */
    public static function uncamelize($camelCaps,$separator='_')
    {
        return strtolower(preg_replace('/([a-z])([A-Z])/', "$1" . $separator . "$2", $camelCaps));
    }


    /**
     * 使用套餐结账
     *
     * @param $package_list     套餐列表
     * @param $dan_ju_data   单据数据
     */
    public static function useTaoCan($package_list, $dan_ju_data)
    {
        $last_data = [];
        foreach ($package_list as $package_k => $package_v) {
            $dan_data = [];
            $result_data = [];
            foreach ($package_v['list'] as $tao_can_k => $tao_can_v) {
                //套餐中的项目商品
                $in_tao_can_data = CommonService::getDanJu($tao_can_v['type'], $tao_can_v['project_id'], $tao_can_v['number'], $dan_ju_data);

                if (empty($in_tao_can_data['result_data'])) {
                    break;//跳出套餐
                }
                $result_data[$tao_can_k] = $in_tao_can_data['result_data'];
                $dan_data[$tao_can_k] = $in_tao_can_data['dan_data'];
            }

            if (empty($result_data) || (!empty($result_data) && count($package_v['list']) != count($result_data))) {
                continue;//跳出套餐
            }

            $i = 0;
            do {
                //判断套餐所有项目商品是否足以扣除
                $is_can_des = CommonService::isCanDec($result_data, $dan_ju_data);
                if ($is_can_des) {
                    //减少单据数量，直到不能减少
                    CommonService::decDanJuData($result_data, $dan_ju_data);
                    $i++;
                }

            } while ($is_can_des);

            if ( $i > 0 ) {
                $rr_data = [];
                foreach ($package_v['list'] as $tao_can_k2 => &$tao_can_v2) {
                    foreach ($dan_data as $d_k => $d_v) {
                        if ($tao_can_v2['type'] == 'goods' && $tao_can_v2['type'] == $d_v['type'] && $tao_can_v2['project_id'] == $d_v['goods_id']) {
                            $rr_data[] = array_merge($dan_data[$tao_can_k2], $tao_can_v2);
                        }

                        if ($tao_can_v2['type'] == 'project' && $tao_can_v2['type'] == $d_v['type'] && $tao_can_v2['project_id'] == $d_v['project_id']) {
                            $rr_data[]= array_merge($dan_data[$tao_can_k2], $tao_can_v2);
                        }
                    }
                }
                $last_data[] = ['list'=>$rr_data, 'number'=>$i,'name'=>$package_v['name'],'price'=>$package_v['price'],'id'=>$package_v['id']];
            }
        }

        return !empty($last_data) ? $last_data : [];
    }


    /**
     * 获取单据的数据
     *
     * @param $type
     * @param $project_id
     * @param $num
     * @param $danju_data
     * @return array
     */
    public static function getDanJu($type, $project_id, $num, $danju_data)
    {
        $result_data = [];
        $dan_data = [];
        foreach ($danju_data as $kk => $vv) {
            if ($type == 'project' && isset($vv['project_id']) && $project_id == $vv['project_id'] && $num <= $vv['number'] ) {
                $dan_data  = $vv;
                $result_data = ['type' => 'project', 'project_id' => $vv['project_id'], 'num' => $num];
            }
            if ($type == 'goods' && isset($vv['goods_id']) && $project_id == $vv['goods_id'] && $num <= $vv['number']) {
                $dan_data  = $vv;
                $result_data = ['type' => 'goods', 'project_id' => $vv['goods_id'], 'num' => $num];
            }

        }
        return ['result_data'=>$result_data,'dan_data'=>$dan_data];
    }


    /**
     * 判断是否足以扣除
     *
     * @return bool
     */
    public static function isCanDec($result_data, $danju_data) {

        $find_num = 0;
        foreach ($result_data as $r_k => $v) {
            foreach ($danju_data as $kk => &$vv) {
                if ($v['type'] == 'project' && $v['project_id'] == $vv['project_id'] && $vv['number'] - $v['num'] >= 0) {
                    $find_num ++ ;
                }
                if ($v['type'] == 'goods' && $v['project_id'] == $vv['project_id'] && $vv['number'] - $v['num'] >= 0) {
                    $find_num ++ ;
                }
            }
        }

        return $find_num == count($result_data) ? true : false;
    }


    /**
     * 减少单据中的数量
     *
     * @param $result_data
     * @param $danju_data
     * @return bool
     */
    public static function decDanJuData($result_data, &$danju_data)
    {
        foreach ($result_data as $r_k => $v) {
            foreach ($danju_data as $kk => &$vv) {
                if ($v['type'] == 'project' && $v['project_id'] == $vv['project_id'] && $vv['number'] - $v['num'] >= 0) {
                    $vv['number'] -= $v['num'];
                }
                if ($v['type'] == 'goods' && $v['project_id'] == $vv['project_id'] && $vv['number'] - $v['num'] >= 0) {
                    $vv['number'] -= $v['num'];
                }
            }
        }
    }


    /**
     * @param $data
     * @param $package_data
     * @param $type
     * @return mixed|void
     */
    public static function decGoodsData($data,$package_data,$type) {

        if (empty($package_data)) {
            return $data;
        }
        $new_package_data = [];
        foreach ($package_data as $package_k => $package_v) {
            foreach ($package_v['list'] as $list_k => $list_v) {
                if ($list_v['type'] == 'project' && $type == 'project') {
                    if (!isset($new_package_data[$list_v['project_id']])){
                        $new_package_data[$list_v['project_id']] = 0;
                    }
                    $new_package_data[$list_v['project_id']] += ($list_v['number'] * $package_v['number']);
                }
                if ($list_v['type'] == 'goods' && $type == 'goods') {
                    if (!isset($new_package_data[$list_v['goods_id']])){
                        $new_package_data[$list_v['goods_id']] = 0;
                    }
                    $new_package_data[$list_v['goods_id']] += ($list_v['number'] * $package_v['number']);
                }
            }
        }
        $result = self::decGoodsOrProject($data,$new_package_data,$type);
        $data_result = [];
        foreach ($result as  $v) {
            $data_result[] = $v;
        }
        return $data_result;
    }

    public static function decGoodsOrProject (&$data,$new_package_data,$type) {

        foreach ($data as $p_k => &$p_v) {

            if (isset($p_v['goods_id']) && isset($new_package_data[$p_v['goods_id']]) && $type == 'goods') {

                if ($new_package_data[$p_v['goods_id']] <= 0) break;

                if ($p_v['goods_num'] >= $new_package_data[$p_v['goods_id']]) {
                    $p_v['goods_num'] -= $new_package_data[$p_v['goods_id']];
                    $new_package_data[$p_v['goods_id']] -= $new_package_data[$p_v['goods_id']];
                    if($data[$p_k]['goods_num'] == 0){
                        unset($data[$p_k]);
                    }
                } else {
                    $new_package_data[$p_v['goods_id']] -= $p_v['goods_num'];
                    $p_v['goods_num'] -= $p_v['goods_num'];
                    unset($data[$p_k]);
                }
            }
            if (isset($p_v['project_id']) && isset($new_package_data[$p_v['project_id']]) && $type == 'project') {
                if ($new_package_data[$p_v['project_id']] <= 0) break;

                if ($new_package_data[$p_v['project_id']] >= 1) {
                    $new_package_data[$p_v['project_id']] -= 1;
                    unset($data[$p_k]);
                }
            }
        }

        return $data;
    }

}
